package com.excel.export.controller;

import com.excel.export.entity.BackLogBean;
import com.excel.export.service.BackLogService;
import com.excel.export.util.ExcelUtil;
import com.excel.export.util.TraceUtil;
import com.excel.export.util.ZipUtil;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author ZH
 * @date 2022年01月16日 16:31:00
 * @version: 1.0.0
 */
@RestController
public class ExcelExportController {
    @Resource
    private BackLogService backLogService;



    /**
     * 单个excel的数据量
     */
    private static final int EXCEL_NUMBER = 5000;
    /**
     * excel文件的后缀名
     */
    private static final String EXCEL_SUFFIX = ".xlsx";
    /**
     * 导出的zip文件名
     */
    private static final String ZIP_FILE_NAME = "待办事项导出合集.zip";
    /**
     * 读取的本地文件路径
     */
    private static final String READ_FILE_PATH = "D:/result.txt";
    /**
     * 写入的本地zip文件路径
     */
    private static final String WRITE_ZIP_PATH = "D:/result.zip";
    /**
     * 写入的zip中文件的名称
     */
    private static final String WRITE_FILE_NAME = "hello.txt";

    /**
     * 大数据量excel导出至zip
     * @Author ZhangH
     * @Date 2022/1/16 18:19
     * @param response
     */
    @RequestMapping(value = "/export")
    public void export(HttpServletResponse response) throws IOException {
        ServletOutputStream outputStream = response.getOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);

        //获取需要导出的数据信息
        List<BackLogBean> list = backLogService.list();
        int totalnumber = list.size();
        /*
         * application/octet-stream
         * 这是应用程序文件的默认值。意思是 未知的应用程序文件 ，浏览器一般不会自动执行或询问执行。
         */
        response.setContentType("application/octet-stream; charset=utf-8");
        /*
         * 在常规的HTTP应答中，Content-Disposition 响应头指示回复的内容该以何种形式展示
         * attachment 意味着消息体应该被下载到本地
         */
        response.setHeader("Content-Disposition", "attachment; filename=" + new String(ZIP_FILE_NAME.getBytes(),"iso-8859-1") );
        TraceUtil traceUtil = new TraceUtil();
        traceUtil.start();
        try {
            for (int i = 0; i < totalnumber / EXCEL_NUMBER + 1; i++) {
                //记录日志的
                TraceUtil trace = new TraceUtil();
                trace.start();
                //取集合中指定部分的数据
                List<BackLogBean> backLogBeanList = this.getBean(list, i);
                //数据写入excel
                SXSSFWorkbook workbook = ExcelUtil.export(backLogBeanList);
                //excel写入zip
                ZipUtil.excelWrite("待办事项"+((EXCEL_NUMBER*i)+1) +"-"+ (backLogBeanList.size()<EXCEL_NUMBER ?(((EXCEL_NUMBER*i)+1)+backLogBeanList.size()-1):EXCEL_NUMBER*(i+1)) + EXCEL_SUFFIX, workbook, zipOutputStream);
                trace.stop("导出第" +(i+1)+ "个excel成功");
            }
            zipOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            zipOutputStream.close();
            outputStream.close();
        }
    }

   /**
    * 读取本地文件，写入zip文件后保存至本地
    * @Author ZhangH
    * @Date 2022/1/16 18:18
    * @return java.lang.String
    */
    @RequestMapping("/file")
    public String file() {
        File file = new File(READ_FILE_PATH);
        if (!file.exists()) {
            System.out.println(READ_FILE_PATH + " is not exist");
            return "failed";
        }

        FileInputStream fis = null;
        FileOutputStream fos = null;
        ZipOutputStream zipOutputStream = null;
        try {
            fis = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            fos = new FileOutputStream(new File(WRITE_ZIP_PATH));
            zipOutputStream = new ZipOutputStream(fos);
            zipOutputStream.putNextEntry(new ZipEntry(WRITE_FILE_NAME));
            int c;
            while ((c = fis.read(buffer)) != -1) {
                zipOutputStream.write(buffer, 0, c);
            }
            zipOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (zipOutputStream != null) {
                try {
                    zipOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "success";
    }


    /**
     * 获取集合中指定下标的数据
     * @Author ZhangH
     * @Date 2022/1/16 15:38
     * @param beans  所有数据
     * @param count  计算开始和结束下标指针
     * @return java.util.List<com.dotwait.excel.entity.BackLogBean>
     */
    public List<BackLogBean> getBean(List<BackLogBean> beans, int count){
        //开始下标结束下标
        int startIndex = count*EXCEL_NUMBER, endIndex= startIndex + EXCEL_NUMBER-1>beans.size()?(count*EXCEL_NUMBER+(beans.size()-count*EXCEL_NUMBER)-1):startIndex + EXCEL_NUMBER-1;
        List<BackLogBean> result = new ArrayList<BackLogBean>();
        for (int i = startIndex; i <= endIndex; i++) {
            result.add(beans.get(i));
        }
        return result;
    }

}
